home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / appl / napsaterm / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-12  |  11.1 KB  |  519 lines

  1. RCS_ID_C "$Id: display.c,v 1.5 1993/07/12 22:51:47 ppessi Exp $";
  2. /* 
  3.  * display.c --- generic display routines for niftyterm
  4.  *
  5.  * Copyright 1989, Chris Newman
  6.  * All Rights Reserved
  7.  * Permission is granted ot copy, modify, and use this as long
  8.  * as this notice remains intact.  This is a nifty program.
  9.  *
  10.  * DISCLAIMER: the author (and maintainer) of this program is not responsible
  11.  * for any damage or other problems caused by it.
  12.  *
  13.  * $Author: ppessi $ $Revision: 1.5 $ $Date: 1993/07/12 22:51:47 $
  14.  *
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <exec/memory.h>
  20. #include <clib/exec_protos.h>
  21. #include "nifty.h"
  22. #include "display.h"
  23. #include "dispmacros.h"
  24.  
  25. #ifdef __SASC
  26. extern struct ExecBase *SysBase;
  27. #include <pragmas/exec_sysbase_pragmas.h>
  28. #endif
  29. static char AllocMemError[] = PROGNAME ": PANIC! AllocMem error\n";
  30.  
  31. /* display specific routines called:
  32.  * dsscroll(), dsinvert(), dsstyle(), dsputs()
  33.  * idssetfont()
  34.  */
  35.  
  36. /* global display structure */
  37. struct nifty_display disp;
  38.  
  39. /* global settings in emulate.c needed for soft reset */
  40. extern int vt100_yucky_wrap_mode;
  41. extern int ansi_LNM;
  42. extern int visual;
  43.  
  44. /* global from main needed to set ansi_LNM correctly */
  45. extern int use_stdin;
  46.  
  47. /* allocate the display buffers
  48.  */
  49. void
  50. allocate_display(width,height)
  51. int width, height;
  52. {
  53.     disp.buf = AllocMem((sizeof(char) * (width+1) * height), MEMF_CLEAR);
  54.     disp.sbuf = (short *)AllocMem((sizeof(short) * (width+1) * height), MEMF_CLEAR);
  55.     disp.tabstops = AllocMem((sizeof (char) * width), MEMF_CLEAR);
  56.     disp.maxwidth = width;
  57.     disp.maxheight = height;
  58.     disp.bufwidth = width+1;
  59.     if (disp.buf == NULL || disp.sbuf == NULL || disp.tabstops == NULL) {
  60.     fputs(AllocMemError, stdout);
  61.     exit(-1);
  62.     }
  63. }
  64.  
  65. /* Free up memory allocated for display */
  66. void
  67. free_display()
  68. {
  69.     if(disp.buf) FreeMem(disp.buf, sizeof(char) * (disp.maxwidth + 1) * disp.maxheight);
  70.     if(disp.sbuf) FreeMem(disp.sbuf, sizeof(short) * (disp.maxwidth + 1) * disp.maxheight);
  71.     if(disp.tabstops) FreeMem(disp.tabstops, sizeof(char) * disp.maxwidth);
  72. }
  73.  
  74. /* clear out the display
  75.  */
  76. void
  77. clear_display()
  78. {
  79.     register int y;
  80.      
  81.     for (y = 0; y < disp.maxheight; y++) {
  82.     disp.plines[y] = disp.buf+y*disp.bufwidth;
  83.     disp.pstyles[y] = disp.sbuf+y*disp.bufwidth;
  84.     STYLEFLAG(y) = 0;
  85.     LINELENST(y) = 0;
  86.     }
  87.     disp.curx = disp.cury = 0;
  88. }
  89.  
  90. /* clear out the tab stops
  91.  */
  92. void
  93. clear_tabstops()
  94. {
  95.     register int i;
  96.  
  97.     for (i=0; i<disp.maxwidth; i++)
  98.     disp.tabstops[i] = 0;
  99. }
  100.  
  101. /* initialize tabstops to 8 characters
  102.  */
  103. void
  104. init_tabstops()
  105. {
  106.     register int i;
  107.  
  108.     for (i=0; i<disp.maxwidth; i++)
  109.     disp.tabstops[i] = (i % 8) == 0;
  110. }
  111.  
  112. /* reset the display
  113.  */
  114. void
  115. reset_display(soft)
  116. int soft;
  117. {
  118.     if(!soft) {
  119.         clear_display();
  120.     disp.scrolldefault = 1;
  121.     }
  122.     (void) dsstyle(STYLESOFF);
  123.     disp.visual = visual;
  124.     disp.insert = disp.origin = disp.scrolltop = disp.savex = disp.savey = 0;
  125.     disp.scrollbot = soft ? disp.winheight - 1 : disp.maxheight;
  126.     disp.scrollskip = disp.scrolldefault;
  127.     disp.wrap = 1;
  128.     init_tabstops();
  129. }
  130.  
  131. /* move cursor to x, y
  132.  */
  133. void
  134. dscursorto(x, y)
  135. int x, y;
  136. {
  137.     int    wflag;
  138.     
  139.     if (disp.origin) {
  140.     y += disp.scrolltop;
  141.     MAXBOUNDCK(y, disp.scrollbot);
  142.     } else
  143.     SLIMITCK(y, disp.winheight);
  144.     if (disp.cury != y)
  145.     idssetfont(disp.style, disp.cury = y);
  146.     wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  147.     disp.curx = SLIMIT(x, disp.winwidth/wflag);
  148. }
  149.  
  150. /* return size of the current window
  151.  */
  152. void 
  153. dsgetsize(x, y)
  154. int *x, *y;
  155. {
  156.     *x = disp.winwidth;
  157.     *y = disp.winheight;
  158. }
  159.  
  160. /* get cursor position
  161.  */
  162. void
  163. dsgetcursor(x, y)
  164. int *x, *y;
  165. {
  166.     *x = disp.curx;
  167.     *y = disp.cury;
  168. }
  169.  
  170. /* display style changes
  171.  */
  172. int 
  173. dsstyle(style)
  174. int style;
  175. {
  176.     switch (style) {
  177.     case BOLD1: /* bold on */
  178.         disp.style |= BOLD;
  179.         break;
  180.     case BOLD0: /* bold off */
  181.         disp.style &= ~BOLD;
  182.         break;
  183.     case ITALIC1: /* italic on */
  184.         disp.style |= ITALIC;
  185.         break;
  186.     case ITALIC0: /* italic off */
  187.         disp.style &= ~ITALIC;
  188.         break;
  189.     case UNDERLINE1: /* underline on */
  190.         disp.style |= UNDERLINE;
  191.         break;
  192.     case UNDERLINE0: /* underline off */
  193.         disp.style &= ~UNDERLINE;
  194.         break;
  195.     case INVERSE1: /* inverse on */
  196.         disp.style |= INVERSE;
  197.         break;
  198.     case INVERSE0: /* inverse off */
  199.         disp.style &= ~INVERSE;
  200.         break;
  201.     case BLINK1:
  202.         disp.style |= FLASH;
  203.         break;
  204.     case BLINK0:
  205.         disp.style &= ~FLASH;
  206.         break;
  207.     case ALTERNATE1:
  208.         disp.style |= ALTERNATE;
  209.         break;
  210.     case ALTERNATE0:
  211.         disp.style &= ~ALTERNATE;
  212.         break;
  213.     case STYLESOFF: /* turn off all */
  214.         disp.style = 0;
  215.         break;
  216.     case SAVE_STYLE: /* save the style */
  217.         disp.savestyle = disp.style;
  218.         break;
  219.     case RESTORE_STYLE: /* restore the saved style */
  220.         disp.style = disp.savestyle;
  221.         break;
  222.     case DWIDTH1: /* double width */
  223.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == (DOUBLE1 | DOUBLE2))
  224.         break;
  225.         STYLEFLAG(disp.cury) |= DOUBLE1 | DOUBLE2;
  226.         redraw_line(disp.cury);
  227.         break;
  228.     case DWIDTHTOP:/* double width/height top */
  229.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE1)
  230.         break;
  231.         STYLEFLAG(disp.cury) &= ~DOUBLE2;
  232.         STYLEFLAG(disp.cury) |= DOUBLE1;
  233.         redraw_line(disp.cury);
  234.         break;
  235.     case DWIDTHBOT: /* double width/height bottom */
  236.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE2)
  237.         break;
  238.         STYLEFLAG(disp.cury) &= ~DOUBLE1;
  239.         STYLEFLAG(disp.cury) |= DOUBLE2;
  240.         redraw_line(disp.cury);
  241.         break;
  242.     case DWIDTH0: /* single width, single height */
  243.         if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == 0)
  244.         break;
  245.         STYLEFLAG(disp.cury) &= ~DOUBLE_MASK;
  246.         redraw_line(disp.cury);
  247.         break;
  248.     default: /* style unavailable */
  249.         return -1;
  250.     }
  251.     idssetfont(disp.style, disp.cury);
  252.  
  253.     return 0;
  254. }
  255.  
  256. /* check if cursor can move down without scrolling, and move cursor if it can.
  257.  */
  258. int 
  259. dscheckdown()
  260. {
  261.     return (disp.cury < disp.scrollbot ? ++disp.cury : 0);
  262. }
  263.  
  264. /* move the cursor
  265.  */
  266. void
  267. dscursormove(move, n)
  268. int move, n;
  269. {
  270.     int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  271.  
  272.     if (n<1)  n=1;
  273.     switch (move) {
  274.     case CURSOR_UP: case REVERSE_INDEX:
  275.         disp.cury -= n;
  276.         if (disp.cury < disp.scrolltop) {
  277.         if (move == REVERSE_INDEX) {
  278.             dsscroll(disp.scrolltop,disp.scrollbot - disp.scrolltop + 1,disp.cury - disp.scrolltop);
  279.         }
  280.         disp.cury = disp.scrolltop;
  281.         }
  282.         break;
  283.         
  284.     case CURSOR_RIGHT:
  285.         disp.curx += n;
  286.         SLIMITCK(disp.curx, disp.winwidth/wflag);
  287.         break;
  288.  
  289.     case CURSOR_LEFT:
  290.         disp.curx -= n;
  291.         MINBOUNDCK(disp.curx, 0);
  292.         break;
  293.  
  294.     case DOWN1_AND_SCROLL:
  295.         {
  296.         int scrolltop = disp.scrolltop;
  297.         int scrollheight = disp.scrollbot - scrolltop;
  298.         int scrollsize;
  299.         
  300.         if (disp.scrollskip > n)
  301.             n = disp.scrollskip;
  302.         if (disp.cury > disp.scrollbot) {
  303.             scrollheight = disp.winheight;
  304.             scrolltop = 0;
  305.         }
  306.         if (n > (scrollsize = (scrollheight >> 1)))
  307.             n = scrollsize ? scrollsize : 1;
  308.         disp.cury -= n-1;
  309.         dsscroll(scrolltop, scrollheight + 1, n);
  310.         }
  311.         break;
  312.  
  313.     case CURSOR_DOWN: case NEXT_LINE: case INDEX:
  314.         if (disp.cury <= disp.scrollbot && (disp.cury+=n) > disp.scrollbot) {
  315.         if (move == CURSOR_DOWN) {
  316.             disp.cury = disp.scrollbot;
  317.         } else {
  318.             dsscroll(disp.scrolltop,
  319.                  disp.scrollbot - disp.scrolltop + 1,
  320.                  disp.cury - disp.scrollbot + disp.scrollskip - 1);
  321.             disp.cury = disp.scrollbot - disp.scrollskip + 1;
  322.         }
  323.         } else if (disp.cury > disp.scrollbot && (disp.cury+=n) > disp.winheight-1) {
  324.         if (move == CURSOR_DOWN) {
  325.             disp.cury = disp.winheight-1;
  326.         } else {
  327.             dsscroll(0, disp.winheight, disp.cury - disp.winheight + disp.scrollskip);
  328.             disp.cury = disp.winheight - disp.scrollskip;
  329.         }
  330.         }
  331.         if (move != NEXT_LINE)
  332.         break;
  333.         /* fall through */
  334.     case BEGIN_LINE:
  335.         disp.curx = 0;
  336.         break;
  337.  
  338.     case END_LINE:
  339.         disp.curx = disp.winwidth/wflag-1;
  340.         break;
  341.  
  342.     case BOTTOM_HOME:
  343.         disp.curx = 0;
  344.         disp.cury = disp.winheight-1;
  345.         break;
  346.  
  347.     case SAVE_CURSOR:
  348.         disp.savex = disp.curx;
  349.         disp.savey = disp.cury;
  350.         (void) dsstyle(SAVE_STYLE);
  351.         break;
  352.  
  353.     case RESTORE_CURSOR:
  354.         disp.curx = disp.savex;
  355.         disp.cury = disp.savey;
  356.         (void) dsstyle(RESTORE_STYLE);
  357.         break;
  358.  
  359.     case INSERT_LINE:
  360.         dsscroll(disp.cury, disp.scrollbot-disp.cury+1, -n);
  361.         break;
  362.  
  363.     case DELETE_LINE:
  364.         dsscroll(disp.cury, disp.scrollbot-disp.cury+1, n);
  365.         break;
  366.  
  367.     case INSERT_CHAR: {
  368.         char insertme[MAXWIDTH];
  369.         int temp;
  370.         
  371.         disp.insert++;
  372.         insertme[SLIMIT(n,MAXWIDTH)] = '\0';
  373.         for (temp = n; --temp >= 0; insertme[temp] = ' ');
  374.         temp = disp.curx;
  375.         dsputs(insertme);
  376.         disp.curx = temp;
  377.         disp.insert--;
  378.         }
  379.         break;
  380.  
  381.     case TAB_STOP:
  382.         if (n > 1) {
  383.         while (disp.curx < disp.winwidth/wflag-1 && ++disp.curx % n);
  384.         } else {
  385.         while (disp.curx < disp.winwidth/wflag-1 &&
  386.                !disp.tabstops[++disp.curx]);
  387.         }
  388.         break;
  389.     }
  390.     idssetfont(disp.style, disp.cury);
  391. }
  392.  
  393. /* miscellaneous terminal functions
  394.  */
  395. void
  396. dsfunction(what)
  397. int what;
  398. {
  399.     int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
  400.  
  401.     switch(what) {
  402.     case ERASETO_EOS:
  403.         if (disp.cury < disp.winheight-1)
  404.         dsclear(0, disp.cury+1, disp.winwidth/wflag-1, disp.winheight-1);
  405.         /* fall through */
  406.     case ERASETO_EOL:
  407.         if (disp.curx < disp.winwidth/wflag-1)
  408.         dsclear(disp.curx, disp.cury, disp.winwidth/wflag-1, disp.cury);
  409.         break;
  410.  
  411.     case ERASETO_SOS:
  412.         if (disp.cury)
  413.         dsclear(0, 0, disp.winwidth/wflag-1, disp.cury-1);
  414.         /* fall through */
  415.     case ERASETO_SOL:
  416.         if (disp.curx)
  417.         dsclear(0, disp.cury, disp.curx, disp.cury);
  418.         break;
  419.  
  420.     case ERASE_LINE:
  421.         dsclear(0, disp.cury, disp.winwidth/wflag-1, disp.cury);
  422.         break;
  423.  
  424.     case RESET_DISPLAY:
  425.         reset_display(1);
  426.         break;
  427.  
  428.     case SCROLL_UP:
  429.         dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, 1);
  430.         break;
  431.  
  432.     case SCROLL_DOWN:
  433.         dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, -1);
  434.         break;
  435.  
  436.     case ORIGIN_ON:
  437.         disp.origin = 1;
  438.         break;
  439.  
  440.     case ORIGIN_OFF:
  441.         disp.origin = 0;
  442.         break;
  443.  
  444.     case BLOCK_CURSOR:
  445.         disp.visual |= CUR_BLOCK;
  446.         break;
  447.  
  448.     case UNDERLINE_CURSOR:
  449.         disp.visual &= ~CUR_BLOCK;
  450.         break;
  451.  
  452.     case INVISIBLE_CURSOR:
  453.         disp.visual |= CUR_INVISIBLE;
  454.         break;
  455.  
  456.     case VISIBLE_CURSOR:
  457.         disp.visual &= ~CUR_INVISIBLE;
  458.         break;
  459.  
  460.     case WRAP_ON:
  461.         disp.wrap = 1;
  462.         break;
  463.  
  464.     case WRAP_OFF:
  465.         disp.wrap = 0;
  466.         break;
  467.  
  468.     case INSERT_ON:
  469.         disp.insert = 1;
  470.         break;
  471.  
  472.     case INSERT_OFF:
  473.         disp.insert = 0;
  474.         break;
  475.  
  476.     case SET_TAB:
  477.         disp.tabstops[disp.curx] = 1;
  478.         break;
  479.  
  480.     case CLEAR_TAB:
  481.         disp.tabstops[disp.curx] = 0;
  482.         break;
  483.  
  484.     case CLEAR_ALL_TABS:
  485.         clear_tabstops();
  486.         break;
  487.     }
  488.     idssetfont(disp.style, disp.cury);
  489. }
  490.  
  491. /* set the scrolling region
  492.  */
  493. void
  494. dssetscroll(top,bot)
  495. int top,bot;
  496. {
  497.     if (top)
  498.     top--;
  499.     if (bot)
  500.     bot--;
  501.     if (bot - top < 1)
  502.     disp.scrolltop = 0, disp.scrollbot = disp.winheight-1;
  503.     else {
  504.     if (top >= disp.winheight)
  505.         top = 0;
  506.     if (bot >= disp.winheight)
  507.         bot = disp.winheight-1;
  508.     disp.scrolltop = top;
  509.     disp.scrollbot = bot;
  510.     }
  511.     disp.curx = 0;
  512.     disp.cury = disp.scrolltop;
  513.     if (disp.scrolltop || disp.scrollbot < disp.winheight-1)
  514.     disp.scrollskip = 1;
  515.     else
  516.     disp.scrollskip = disp.scrolldefault;
  517.     idssetfont(disp.style, disp.cury);
  518. }
  519.